﻿using System;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Data.Objects;
using Microsoft.Practices.Unity;
using DddCms.Domain.Model;
using DddCms.Domain.Utility;
using DddCms.Infrastructure.Authentication;

namespace DddCms.Infrastructure.Repository
{
    /// <summary>
    /// Interface and adapte DbContext
    /// </summary>
    public interface IDataContext
    {
        /// <summary>
        /// Entity Property
        /// </summary>
        IDbSet<User> User { get; set; }

        /// <summary>
        /// Entity Property
        /// </summary>
        IDbSet<Role> Role { get; set; }

        /// <summary>
        /// Save in database
        /// </summary>
        /// <returns></returns>
        int Save();

        /// <summary>
        /// Save in database
        /// </summary>
        /// <returns></returns>
        void ResolveInstance(Type info, object value);
    }

    /// <summary>
    /// Class use for communicate with Entity Framework Code First
    /// </summary>
    public class DataContext : DbContext, IDataContext
    {
        [Dependency]
        public IUnityContainer UnityContainer { get; set; }

        [Dependency]
        public IPasswordUtil PasswordUtil { get; set; }


        /// <summary>
        /// Constructor, Set database name
        /// </summary>
        public DataContext()
            : base("DataDddCms")
        {
            PasswordUtil = new PasswordUtil();
            ((IObjectContextAdapter)this).ObjectContext.ObjectMaterialized +=
                this.OnObjectMaterialized;
        }
       
        /// <summary>
        /// Todo : Faire les tests
        /// </summary>
        protected void OnObjectMaterialized(object sender, ObjectMaterializedEventArgs e)
        {
            // Resolve entity dependency
            UnityContainer.BuildUp(e.Entity.GetType().BaseType, e.Entity);
        }

        
        /// <summary>
        /// Set contraint validation at entity
        /// </summary>
        /// <param name="modelBuilder"></param>
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Entity<User>().Property(p => p.Email).HasMaxLength(100);
            modelBuilder.Entity<User>().Ignore(p => p.LogWriter);

        }

        /// <summary>
        /// Entity Property
        /// </summary>
        public virtual IDbSet<User> User { get; set; }

        /// <summary>
        /// Entity Property
        /// </summary>
        public virtual IDbSet<Role> Role { get; set; }

        public virtual int Save()
        {
            return this.SaveChanges();
        }

        public virtual void ResolveInstance(Type info, object value)
        {
            UnityContainer.BuildUp(info, value);
        }
    }

}
